package com.su.kddq.service.user.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.app.models.AlipayTradeAppPayResponse;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.su.kddq.constant.OrderStateConstant;
import com.su.kddq.constant.OssConst;
import com.su.kddq.constant.PayDataConstant;
import com.su.kddq.entity.user.*;
import com.su.kddq.entity.user.vo.UserRegister;
import com.su.kddq.mapper.courier.CourierOrderMapper;
import com.su.kddq.mapper.user.*;
import com.su.kddq.security.security.TokenManager;
import com.su.kddq.service.courier.CourierStatusService;
import com.su.kddq.service.courier.RoleService;
import com.su.kddq.service.user.UserService;
import com.su.kddq.utils.AliPayConfig;
import com.su.kddq.utils.Md5Util;
import com.su.kddq.utils.RandomUtil;
import com.su.kddq.utils.result.ResultCode;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author sx
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private CourierStatusService courierStatusService;

    @Autowired
    private com.aliyun.dysmsapi20170525.Client client;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SchoolMapper schoolMapper;

    @Autowired
    private OssConst ossConst;

    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private PayOrderMapper payOrderMapper;

    @Autowired
    private UserWalletMapper userWalletMapper;

    @Autowired
    private CourierOrderMapper courierOrderMapper;

    @Autowired
    private AppVersionMapper appVersionMapper;

    @Override
    public Map<String, Object> getUserInfo(String id) {
        Map<String, Object> result = new HashMap<>();
        User user = userMapper.selectById(id);
        if (StringUtils.isEmpty(user)) {
            return result;
        }
        //根据用户id获取角色
        List<Integer> roleList = roleService.selectPermissionValueByUserId(user.getRid());
        if (roleList.size() == 0) {
            //前端框架必须返回一个角色，否则报错，如果没有角色，返回一个空角色
            roleList.add(0);
        }
        if (roleList.get(0) == 2) {
            CourierStatus courierStatus = courierStatusService.getOne(new QueryWrapper<CourierStatus>().eq("uid", user.getId()));
            result.put("courierStatus", courierStatus);
        } else {
            result.put("courierStatus", -1);
        }
        result.put("phone", user.getPhone());
        result.put("avatar", user.getAvatar());
        result.put("roles", roleList);
        result.put("id", user.getId());
        return result;
    }


    @Override
    public User selectByUsername(String phone) {
        return this.getOne(new QueryWrapper<User>().eq("phone", phone));
    }

    @Override
    public String UpUserAvatar(MultipartFile file) {
        // Endpoint以杭州为例，其它Region请按实际情况填写。
        // 云账号AccessKey有所有API访问权限，建议遵循阿里云安全最佳实践，创建并使用RAM子账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建。
        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(ossConst.getENDPOINT(), ossConst.getKEYID(), ossConst.getKEYSECERT());
        try {
            // 上传文件流。
            InputStream inputStream = file.getInputStream();
            //创建UUID随机数
            UUID uuid = UUID.randomUUID();
            //获取文件名称
            String filename = file.getOriginalFilename();
            filename = uuid + filename;
            filename = "UserAvatar" + "/" + filename;
            ossClient.putObject(ossConst.getBUCKETNAME(), filename, inputStream);
            String url = "https://" + ossConst.getBUCKETNAME() + "." + ossConst.getENDPOINT() + "/" + filename;
            return url;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
    }

    @Override
    public boolean sendMsm(String phone) {
        Object value = redisTemplate.opsForValue().get(phone);
        if (StringUtils.isEmpty(value)) {
            Map code = new HashMap();
            code.put("code", RandomUtil.getFourBitRandom());
            SendSmsRequest sendSmsRequest = new SendSmsRequest();
            // 复制代码运行请自行打印 API 的返回值
            try {
                sendSmsRequest.setPhoneNumbers(phone);
                sendSmsRequest.setSignName("信工开源");
                sendSmsRequest.setTemplateCode("SMS_205396563");
                sendSmsRequest.setTemplateParam(JSON.toJSONString(code));
                SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
                String recode = sendSmsResponse.getBody().getCode();
                redisTemplate.opsForValue().set(phone, code.get("code"), 5, TimeUnit.MINUTES);
                return recode.equals("OK") ? true : false;
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
        } else {
            return true;
        }
    }

    @Override
    public boolean register(UserRegister userRegister) {
        if (!StringUtils.isEmpty(userRegister.getCode()) && !StringUtils.isEmpty(userRegister.getPhone())) {
            User selectOne = userMapper.selectOne(new QueryWrapper<User>().eq("phone", userRegister.getPhone()));
            if (!StringUtils.isEmpty(selectOne)) {
                return false;
            }
            Object code = redisTemplate.opsForValue().get(userRegister.getPhone());
            if (StringUtils.isEmpty(code)) {
                return false;
            } else if (userRegister.getCode().equals(code.toString())) {
                User user = new User();
                BeanUtils.copyProperties(userRegister, user);
                user.setRid(1);
                user.setPassword(Md5Util.encrypt(userRegister.getPassword()));
                try {
                    userMapper.insert(user);
                    School school = new School();
                    school.setUid(user.getId());
                    school.setSchoolId(userRegister.getSchoolId());
                    school.setSchool_name(userRegister.getSchoolName());
                    schoolMapper.insert(school);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            } else {
                return false;
            }
        }
        return false;
    }

    @Override
    public Map<String, String> reFreshToken(Map dataMap) {
        Map<String, String> map = new HashMap<>(2);
        try {
            String refresh = dataMap.get("refresh").toString();
            if (!StringUtils.isEmpty(refresh)) {
                String phone = tokenManager.getUserFromToken(refresh);
                Object reFreshFromRedis = redisTemplate.opsForValue().get(phone);
                if (!StringUtils.isEmpty(reFreshFromRedis) && reFreshFromRedis.equals(refresh)) {
                    //开始token续期
                    User user = this.getOne(new QueryWrapper<User>().select("id").eq("phone", phone));
                    map = tokenManager.createToken(String.valueOf(user.getId()), phone);
                    map.put("isRefresh", "true");
                    return map;
                }
            }
            map.put("isRefresh", "false");
            return map;
        } catch (Exception e) {
            map.put("isRefresh", "false");
            return map;
        }
    }

    @Override
    public Map<String, Object> toPay(String money) {
        Map<String, Object> payMap = new HashMap();
        try {
            /*int count = Integer.parseInt(money);
            if (count < 10 || count % 5 != 0) {
                payMap.put("isPay", false);
                return payMap;
            }*/
            String uid = SecurityContextHolder.getContext().getAuthentication().getName();
            String payOrderId = UUID.randomUUID().toString().replace("-", "");
            PayOrder payOrder = new PayOrder();
            payOrder.setMoney(Float.valueOf(money));
            payOrder.setUid(Integer.parseInt(uid));
            payOrder.setCreatTime(new Date());
            payOrder.setUpdateTime(new Date());
            payOrder.setStatus(OrderStateConstant.RECHARGE_ORDER_STATE_NO);
            payOrder.setPayOrderId(payOrderId);
            payOrderMapper.insert(payOrder);
            //1. 设置参数（全局只需设置一次）
            Factory.setOptions(AliPayConfig.getOptions());
            AlipayTradeAppPayResponse response = Factory.Payment.App()
                    .pay(PayDataConstant.name, payOrderId, money);
            // 3. 处理响应或异常
            if (ResponseChecker.success(response)) {
                payMap.put("isPay", true);
                payMap.put("payBody", response.body);
                payMap.put("payOrderId",payOrderId);
            } else {
                payMap.put("isPay", false);
            }
            return payMap;
        } catch (Exception e) {
            e.printStackTrace();
            payMap.put("isPay", false);
            return payMap;
        }
    }

    @Override
    public UserWallet queryWallet() {
        String uid = SecurityContextHolder.getContext().getAuthentication().getName();
        UserWallet userWallet = userWalletMapper.selectOne(new QueryWrapper<UserWallet>().eq("uid", uid));
        return StringUtils.isEmpty(userWallet) ? null : userWallet;
    }

    @Override
    public Map changeMyStatus(Map map) {
        Map isChangeMap = new HashMap(2);
        try {
            boolean isStart = (boolean) map.get("isStart");
            Integer uid = (Integer) map.get("id");
            User user = this.getOne(new QueryWrapper<User>().eq("id", uid));
            Role role = roleService.getOne(new QueryWrapper<Role>().eq("id", user.getRid()));
            if (role.getRoleCode() == 2) {
                //检查是否有代送订单
                Integer count = courierOrderMapper.queryIshasWaitOrder(uid);
                if (count > 0) {
                    //有代送订单不能修改状态
                    isChangeMap.put("isChange", false);
                    isChangeMap.put("code", ResultCode.NO_OUTLINE);
                    return isChangeMap;
                }
                if (isStart) {
                    courierStatusService.update(new UpdateWrapper<CourierStatus>().eq("uid", uid).set("status", OrderStateConstant.COURIER_STATUS_OUTLINE));
                } else {
                    courierStatusService.update(new UpdateWrapper<CourierStatus>().eq("uid", uid).set("status", OrderStateConstant.COURIER_STATUS_ONLINE));
                }
                isChangeMap.put("isChange", true);
                return isChangeMap;
            }
            isChangeMap.put("isChange", false);
            isChangeMap.put("code", ResultCode.NO_PERMISSION);
            return isChangeMap;
        } catch (Exception e) {
            isChangeMap.put("isChange", false);
            isChangeMap.put("code", ResultCode.ERROR);
            log.error(e.getMessage());
            return isChangeMap;
        }
    }

    @Override
    public Map checkUpdate(String version) {
        Map map = new HashMap();
        if (StringUtils.isEmpty(version)) {
            map.put("isUpdate", false);
            map.put("code", ResultCode.NO_VERSION);
            return map;
        }
        AppVersion appVersion = appVersionMapper.selectOne(new QueryWrapper<AppVersion>().orderByDesc("app_version").last("limit 1"));
        if (version.equals(appVersion.getAppVersion())) {
            map.put("isUpdate", false);
            map.put("code", ResultCode.NO_UPDATE);
            map.put("version_info", appVersion);
            return map;
        }

        map.put("isUpdate", true);
        map.put("version_info", appVersion);
        return map;

    }

    @Override
    public IPage<PayOrder> queryPayOrder(Integer pageNum,Integer pageSize) {
        String uid = SecurityContextHolder.getContext().getAuthentication().getName();
        //分页Ipage<PayOrder> new page(pageNum, pageSize)
        IPage<PayOrder> page = new Page<>(pageNum, pageSize);
        //降序
        QueryWrapper<PayOrder> queryWrapper = new QueryWrapper<>();
        //查询一个月以内的订单流水
        queryWrapper.eq("uid",uid).last("and date_format(creat_time, '%Y-%m') = date_format(now(),'%Y-%m') ORDER BY creat_time DESC");
        IPage<PayOrder> orderIPage = payOrderMapper.selectPage(page, queryWrapper);
        return orderIPage;
    }


}
